#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <map>
#include <cstdio>
using namespace std;

#define X first
#define Y second
#define mp make_pair

typedef pair<int, int> pii;
const int N = 120;
const int INF = (int)1e9 + 10;
const int E = (int)4e5 + 10;
vector <int> startG[N];
map < pair<pii, pii>, int> indexVertex;

int maxDays = 0;

struct Edge
{
	int a, b;
	int flow, cap;
	Edge () {}
	Edge (int a, int b, int flow, int cap) : a(a), b(b), flow(flow), cap(cap) {}
};

int q[E];
int ptr[E];
int dist[E];
Edge listEdge[E];
vector <int> g[E];
pair<pii, pii> vertexInfo[E];
int indE = 0;
int countVertex;
vector<int> carsInVertex[N];
vector <pii> daysInfo[N];

int getIndex(int type, int a, int b, int day)
{
	if (a > b)
		swap(a, b);
	int sz = indexVertex.size();
	pair<pii, pii> state = mp(mp(type, a), mp(b, day));
	if (indexVertex.find(state) == indexVertex.end())
	{
		indexVertex[state] = sz;
		vertexInfo[sz] = state;
	}
	return indexVertex[state];
}

void addEdge(int a, int b, int cap)
{
	listEdge[indE++] = Edge(a, b, 0, cap);
	listEdge[indE++] = Edge(b, a, 0, 0);

	g[a].push_back(indE - 2);
	g[b].push_back(indE - 1);
}

void printVertexInfo(int v)
{
	pair<pii, pii> state = vertexInfo[v];
	printf("type = %d, a = %d, b = %d, day = %d\n", state.X.X, state.X.Y, state.Y.X, state.Y.Y);
}

bool bfs(int source, int sink)
{
	int topQ = 0;
	fill(dist, dist + countVertex, INF);
	dist[source] = 0;
	q[topQ++] = source;
	for (int i = 0; i < topQ; i++)
	{
		int v = q[i];
		for (int s = 0; s < (int)g[v].size(); s++)
		{
			int index = g[v][s];
			int to = listEdge[index].b;
			if (listEdge[index].cap - listEdge[index].flow > 0 && dist[to] > dist[v] + 1)
			{
				dist[to] = dist[v] + 1;
				q[topQ++] = to;
			}
		}
	}
	return dist[sink] != INF;
}

int dfs(int v, int en, int flow)
{
	if (v == en || flow == 0)
	{
//		printVertexInfo(v);
		return flow;
	}
	for (int &i = ptr[v]; i < (int)g[v].size(); i++)
	{
		int index = g[v][i];
		int to = listEdge[index].b;
		if (listEdge[index].cap - listEdge[index].flow > 0 && dist[to] == dist[v] + 1)
		{
			int tmp = listEdge[index].cap - listEdge[index].flow;
			tmp = dfs(to, en, min(flow, tmp));
			if (tmp > 0)
			{
				listEdge[index].flow += tmp;
				listEdge[index ^ 1].flow -= tmp;
//				printVertexInfo(v);
				return tmp;
			}
		}
	}
	return 0;
}

int findMaxFlow(int source, int sink, int k)
{
	int flow = 0;
	while (bfs(source, sink) && flow < k)
	{
		fill(ptr, ptr + countVertex, 0);
		int curFlow = 0;
		while (curFlow = dfs(source, sink, max(0, k - flow)))
		{
//			printf("Result added flow = %d\n", curFlow);
			flow += curFlow;
		}
	}

	return flow;
}

void refreshGraph()
{
	for (int i = 0; i < indE; i++)
	{
		listEdge[i].flow = 0;
	}
}

int getCar(int v)
{
	int x = carsInVertex[v].back();
	carsInVertex[v].pop_back();
	return x;
}

void getAnswer()
{
	for (int day = 0; day < maxDays; day++)
	{
		for (int i = 0; i < indE; i++)
		{
			int a = listEdge[i].a;
			int b = listEdge[i].b;
			int flow = listEdge[i].flow;
			if (flow == 0)
				continue;
			pair<pii, pii> stateA = vertexInfo[a];
			pair<pii, pii> stateB = vertexInfo[b];

			if (stateA.Y.Y != day || stateB.Y.Y != day)
				continue;
			if (stateA.X.X == 0 && stateB.X.X == 1)
			{
				int v = stateA.Y.X;
				int edgeA = stateB.X.Y;
				int edgeB = stateB.Y.X;
				if (v == edgeA)
					swap(edgeA, edgeB);
				daysInfo[day].push_back(mp(getCar(v), edgeA + 1));
			}
		}
		for (int i = 0; i < daysInfo[day].size(); i++)
		{
			pii state = daysInfo[day][i];
			carsInVertex[state.Y - 1].push_back(state.X);
		}
	}
}

int main()
{
//	freopen ("input.txt", "r", stdin);
	//freopen ("output.txt", "w", stdout);
	int n, m, k, S, T;
	scanf("%d%d%d%d%d", &n, &m, &k, &S, &T);

	S--, T--;
	for (int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		a--, b--;
		startG[a].push_back(b);
		startG[b].push_back(a);
	}

	maxDays = n + k;
	for (int i = 0; i < n; i++)
	{
		for (int day = 0; day < maxDays; day++)
		{
			int a = getIndex(0, 0, i, day);
			int b = getIndex(0, 0, i, day + 1);
			addEdge(a, b, INF);
			for (int s = 0; s < (int)startG[i].size(); s++)
			{
				int to = startG[i][s];
				int edgeIndex = getIndex(1, i, to, day);
				int nextIndex = getIndex(2, i, to, day + 1);
				addEdge(a, edgeIndex, 1);
				addEdge(nextIndex, b, 1);
				if (i < to)
					addEdge(edgeIndex, nextIndex, 1);
			}
		}
	}
	countVertex = (int)indexVertex.size();
	int l = 0, r = maxDays + 1;
	while (r - l > 1)
	{
		refreshGraph();
		int mid = (l + r) / 2;
		int source = getIndex(0, 0, S, 0);
		int sink = getIndex(0, 0, T, mid);

		if (findMaxFlow(source, sink, k) >= k)
			r = mid;
		else
			l = mid;
	}
	printf("%d\n", r);
	int source = getIndex(0, 0, S, 0);
	int sink = getIndex(0, 0, T, r);
	refreshGraph();
	findMaxFlow(source, sink, k);
	for (int i = 1; i <= k; i++)
		carsInVertex[S].push_back(i);
	getAnswer();
	for (int i = 0; i < r; i++)
	{
		printf("%d ", (int)daysInfo[i].size());
		for (int s = 0; s < (int)daysInfo[i].size(); s++)
			printf("%d %d ", daysInfo[i][s].X, daysInfo[i][s].Y);
		puts("");
	}

	return 0;
}